    
 function zoomToFeature(plugin, feature) {

	// get the extent

	var extent = getFeatureExtent(plugin, feature);

	// Create a camera
	var camera = createCameraFromLatLonAltBox(plugin, extent);

	// Zoom
	plugin.getView().setAbstractView(camera);
}


/**
 * Function to calculate the extents of a given feature.
 *
 * If the given feature has a predefined Region then we return that,
 * otherwise we calculate the extents from the features geometry.
 *
 * We try to support all geometry types but if we're passed one we cant deal
 * with then we throw an exception named "UnexpectedGeometryTypeError".
 *
 * @param	plugin		A reference to the Google Earth plugin instance -
 *						this is used to create new LatLonAltBox's
 * @param	feature		The feature to determine the extents of.
 *
 * @return	A LatLonAltBox containing the extents of the feature.
 */
function getFeatureExtent(plugin, feature) {
	var i;
	var list;
	var extents = [];

	if (feature.getType() != 'GEPlugin') {

		// Have a look and see if there's a region defined for this feature. If there is just return that.
		if (feature.getRegion()) {
		confirm("has region");
			return feature.getRegion().getLatLonAltBox();
		}

		// Nope, so look to see if it has a geometry.
		if (feature.getType() == 'KmlPlacemark') {
			extents.push(getGeometryExtents(plugin, feature.getGeometry()));
		}
	}

	if ((feature.getType() == 'GEPlugin' || feature.getType() == 'KmlFolder' || feature.getType() == 'KmlDocument') && feature.getFeatures().hasChildNodes()) {
		list = feature.getFeatures().getChildNodes();
		for (i = 0; i < list.getLength(); i++) {
			extents.push(getFeatureExtent(plugin, list.item(i)));
		}
	}

	return unionExtents(plugin, extents);
}

   
  
 /**
 * Function to calculate the extents of a given geometry.
 *
 * We try to support all geometry types but if we're passed one we cant deal
 * with then we throw an exception named "UnexpectedGeometryTypeError".
 *
 * @param	plugin		A reference to the Google Earth plugin instance -
 *						this is used to create new LatLonAltBox's
 * @param	geometry	The geometry to determine the extents of.
 *
 * @return	A LatLonAltBox containing the extents of the geometry.
 */
function getGeometryExtents(plugin, geometry) {
	var extents = [];
	var new_extent;
	var coords;

	if (geometry.getType() == "KmlMultiGeometry") {
		if (geometry.getGeometries().hasChildNodes()) {
			list = geometry.getGeometries().getChildNodes();
			for (i = 0; i < list.getLength(); i++) {
				geom = list.item(i);
				extents.push(getGeometryExtents(plugin, geom));
			}
		}
	} else if (geometry.getType() == "KmlPolygon") {
		extents.push(getGeometryExtents(plugin, geometry.getOuterBoundary()));

		if (geometry.getInnerBoundaries().hasChildNodes()) {
			list = geometry.getInnerBoundaries().getChildNodes();
			for (i = 0; i < list.getLength(); i++) {
				geom = list.item(i);
				extents.push(getGeometryExtents(plugin, geom));
			}
		}
	} else if (geometry.getType() == "KmlLineString" || geometry.getType() == "KmlLinearRing") {
		if (geometry.getCoordinates().getLength() > 0) {

			coords = geometry.getCoordinates();

			new_extent = plugin.createLatLonAltBox('');

			new_extent.setAltitudeMode(geometry.getAltitudeMode());

			new_extent.setNorth(coords.get(0).getLatitude());
			new_extent.setSouth(coords.get(0).getLatitude());
			new_extent.setEast(coords.get(0).getLongitude());
			new_extent.setWest(coords.get(0).getLongitude());
			new_extent.setMinAltitude(coords.get(0).getAltitude());
			new_extent.setMaxAltitude(coords.get(0).getAltitude());

			for (i = 1; i < coords.getLength(); i++) {
				coord = coords.get(i);
				if (coord.getLatitude() > new_extent.getNorth()) new_extent.setNorth(coord.getLatitude());
				if (coord.getLatitude() < new_extent.getSouth()) new_extent.setSouth(coord.getLatitude());
				if (coord.getLongitude() > new_extent.getEast()) new_extent.setEast(coord.getLongitude());
				if (coord.getLongitude() < new_extent.getWest()) new_extent.setWest(coord.getLongitude());
				if (coord.getAltitude() < new_extent.getMinAltitude()) new_extent.setMinAltitude(coords.get(0).getAltitude());
				if (coord.getAltitude() > new_extent.getMaxAltitude()) new_extent.setMaxAltitude(coords.get(0).getAltitude());
			}
			extents.push(new_extent);
		}
	} else if (geometry.getType() == "KmlModel") {
		new_extent = plugin.createLatLonAltBox('');

		new_extent.setAltitudeMode(geometry.getAltitudeMode());

		new_extent.setNorth(geometry.getLocation().getLatitude());
		new_extent.setSouth(geometry.getLocation().getLatitude());
		new_extent.setEast(geometry.getLocation().getLongitude());
		new_extent.setWest(geometry.getLocation().getLongitude());
		new_extent.setMinAltitude(geometry.getLocation().getAltitude());
		new_extent.setMaxAltitude(geometry.getLocation().getAltitude());

		extents.push(new_extent);
	} else if (geometry.getType() == "KmlPoint") {
		new_extent = plugin.createLatLonAltBox('');

		new_extent.setAltitudeMode(geometry.getAltitudeMode());

		new_extent.setNorth(geometry.getLatitude());
		new_extent.setSouth(geometry.getLatitude());
		new_extent.setEast(geometry.getLongitude());
		new_extent.setWest(geometry.getLongitude());
		new_extent.setMinAltitude(geometry.getAltitude());
		new_extent.setMaxAltitude(geometry.getAltitude());
		extents.push(new_extent);
	} else {
		throw { name: "UnexpectedGeometryTypeError", message: "getGeometryExtent() encountered unknown geometry of type: " + geometry.getType() };
	}
	return unionExtents(plugin, extents);
}

/**
 * Function to union the rectangles stored in a list of LatLonAltBoxs.
 *
 * Note: We try and take altitude into account but, for it to work properly,
 * all the LatLonBoxs should have the same altitude mode. We ignore altitudes
 * from boxes that have a different altitude mode to the first box in the
 * list.
 *
 * @param	plugin	A reference to the Google Earth plugin instance - this is
 *					used to create new LatLonAltBox's
 * @param	extents	A list of LatLonAltBox's to union.
 *
 * @return A LatLonAltBox with the union of the given LatLonAltBox's.
 */
function unionExtents(plugin, extents) {

	var results = null;
	var current_extent;

	try {
		if (extents.length > 0) {
			results = plugin.createLatLonAltBox('');

			current_extent = extents[0];

			results.setAltBox(current_extent.getNorth(),
							  current_extent.getSouth(),
							  current_extent.getEast(),
							  current_extent.getWest(),
							  0.0,
							  current_extent.getMinAltitude(),
							  current_extent.getMaxAltitude(),
							  current_extent.getAltitudeMode());

			for (i = 1; i < extents.length; i++) {
				current_extent = extents[i];
				if (current_extent.getNorth() > results.getNorth()) results.setNorth(current_extent.getNorth());
				if (current_extent.getSouth() < results.getSouth()) results.setSouth(current_extent.getSouth());
				if (current_extent.getEast() > results.getEast()) results.setEast(current_extent.getEast());
				if (current_extent.getWest() < results.getWest()) results.setWest(current_extent.getWest());
				if (current_extent.getAltitudeMode() == results.getAltitudeMode()) {
					if (current_extent.getMinAltitude() < results.getMinAltitude()) results.setMinAltitude(current_extent.getMinAltitude());
					if (current_extent.getMaxAltitude() > results.getMaxAltitude()) results.setMaxAltitude(current_extent.getMaxAltitude());
				}
			}
		}
	} catch (err) {
	}
	return results;
}



function createCameraFromRectangle(plugin, lat1, lng1,  lat2, lng2) {
        var r = 6378700;
        var fov = 20;

        var camera = ge.createCamera('');

        camera.setLatitude((lat1 + lat2) / 2.0);
        camera.setLongitude((lng1 + lng2) / 2.0);
        camera.setHeading(0.0);
        camera.setTilt(0.0);
        var dy = Math.max(lat1, lat2) - Math.min(lat1, lat2);
        var dx = Math.max(lng1, lng2) - Math.min(lng1, lng2);

        var d = Math.max(dy, dx);

        d = d * Math.PI / 180.0;

        var dist = r * Math.tan(d / 2);

        var alt = dist / (Math.tan( fov * Math.PI / 180.0));

        camera.setAltitude(alt);

        return camera;

} 

/**
 * Wrapper for createCameraFromRectangle() to create the camera from a
 * LatLonAltBox.
 *
 * @param	plugin	A reference to the Google Earth plugin instance - this is
 *					used to create new camera's
 *
 * @param	box		The LatLonAltBox to create the camera from.
 *
 * @return A new camera that will show the extents of the LatLonAltBox.
 */
function createCameraFromLatLonAltBox(plugin, box) {
	return createCameraFromRectangle(plugin,
									 box.getNorth(),
									 box.getEast(),
									 box.getSouth(),
									 box.getWest());
}


/**
 * Function to calculate the extents of a given feature.
 *
 * If the given feature has a predefined Region then we return that,
 * otherwise we calculate the extents from the features geometry.
 *
 * We try to support all geometry types but if we're passed one we cant deal
 * with then we throw an exception named "UnexpectedGeometryTypeError".
 *
 * @param	plugin		A reference to the Google Earth plugin instance -
 *						this is used to create new LatLonAltBox's
 * @param	feature		The feature to determine the extents of.
 *
 * @return	A LatLonAltBox containing the extents of the feature.
 */
function getFeatureExtent(plugin, feature) {
	var i;
	var list;
	var extents = [];

	if (feature.getType() != 'GEPlugin') {

		// Have a look and see if there's a region defined for this feature. If there is just return that.
		if (feature.getRegion()) {
			return feature.getRegion().getLatLonAltBox();
		}

		// Nope, so look to see if it has a geometry.
		if (feature.getType() == 'KmlPlacemark') {
			extents.push(getGeometryExtents(plugin, feature.getGeometry()));
		}
	}

	if ((feature.getType() == 'GEPlugin' || feature.getType() == 'KmlFolder' || feature.getType() == 'KmlDocument') && feature.getFeatures().hasChildNodes()) {
		list = feature.getFeatures().getChildNodes();
		for (i = 0; i < list.getLength(); i++) {
			extents.push(getFeatureExtent(plugin, list.item(i)));
		}
	}

	return unionExtents(plugin, extents);
}
